package com.yunhe.commons.dao.impl;

import com.yunhe.commons.dao.BaseDao;
import com.yunhe.commons.dto.Pageable;
import com.yunhe.commons.util.JdbcUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author tianxuan
 * @version V1.0
 * @Date 2017/10/16 0016 下午 5:24
 * @Description: BaseDao的实现
 */
public class BaseDaoImpl<T> implements BaseDao<T>{
    protected Class<T> clazz;  //当前dao对应的实体的class对象

    /**
     * 构造器，获取泛型的实际类型
     */
    @SuppressWarnings("unchecked")
    public BaseDaoImpl() {
        @SuppressWarnings("rawtypes")
        Class clazz = getClass();

        while (clazz != Object.class) {
            Type t = clazz.getGenericSuperclass();  //当前对象的直接超类的 Type
            if (t instanceof ParameterizedType) {
                Type[] args = ((ParameterizedType) t).getActualTypeArguments();//返回表示此类型实际类型参数的 Type 对象的数组
                if (args[0] instanceof Class) {
                    this.clazz = (Class<T>) args[0];
                    break;
                }
            }
            clazz = clazz.getSuperclass();
        }
    }


    protected T queryOne(String sql, Object ... params)  {
        QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
        T query = null;
        try {
            query = qr.query(sql, new BeanHandler<T>(clazz),params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return query;
    }


    protected List<T> queryList(String sql, Object ... params) {
        List paramArr = new ArrayList();
        if(null != params) {
            for( int i = 0; i < params.length; i ++ ) {
                Object o = params[i];
                if(null != o) {
                    paramArr.add(o);
                }
            }
        }
        QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
        List<T> query = null;
        try {
            query = qr.query(sql, new BeanListHandler<T>(clazz), paramArr.toArray());
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return query;
    }


    protected Pageable<T> queryPage(String listSql, String countSql, int offset, int size, Object ... params) {
        //过滤无效参数
        List paramArr = new ArrayList();
        if(null != params) {
            for( int i = 0; i < params.length; i ++ ) {
                Object o = params[i];
                if(null != o) {
                    paramArr.add(o);
                }
            }
        }

        Pageable<T> pageable = new Pageable<>();
        List<T> data = null;
        Long count = 0L;
        QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
        try {
             count = qr.query(countSql, new ScalarHandler<>(),paramArr.toArray());  //总数
            if(count > 0) {
                paramArr.add(offset );
                paramArr.add(size );
                listSql += " limit ?,? ";
                pageable.setPage(offset/size+1);
                pageable.setSize(size);
                data = qr.query(listSql, new BeanListHandler<T>(clazz), paramArr.toArray());  //当页数据
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        pageable.setTotal(count.intValue());
        pageable.setRows(data);
        return pageable;
    }



    protected int cud(String sql, Object... params) {
        int rows = 0;
        QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
        try {
            rows = qr.update(sql, params);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException("cud执行失败");
        }
        return rows;
    }

    protected Long insert(String sql, Object... params) {
        Long key;
        QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
        try {
            key = qr.insert(sql, new ScalarHandler<Long>(), params);
        } catch (SQLException e) {

            throw new RuntimeException(e);
        }
        return key;
    }


}
